package com.net.jef.util;

import java.io.UnsupportedEncodingException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.citrus.service.uribroker.interceptor.URIBrokerInterceptor;
import com.alibaba.citrus.service.uribroker.uri.URIBroker;
import com.alibaba.citrus.util.StringEscapeUtil;
import com.alibaba.citrus.util.i18n.LocaleUtil;

public class MessageFormatURIBroker implements URIBrokerInterceptor {
    private static Map cachedURI = new HashMap();
    @Override
    public void perform(URIBroker broker) {
        this.renderParametrizeURI(broker);

    }

    public String renderParametrizeURI(URIBroker broker) {
        String source=broker.render();
  
        String charset =  LocaleUtil.getContext().getCharset().name();
        URIPramPair pair = (URIPramPair) cachedURI.get(source);

        if (pair == null) {
            parserParameters(source);
            pair = (URIPramPair) cachedURI.get(source);
        }

        List list = pair.paramList;

        if (list.size() > 0) {
            Object[] objs = new Object[list.size()];

            for (int i =  0; i < list.size(); i++) {
                String param = (String) list.get(i);

                // assign to object array
         
                Object value = broker.getQuery().get(param);

                if (value != null) {
                    try {
                        objs[i] = StringEscapeUtil.escapeURL(value.toString(), charset); // url的servletPath和pathInfo由utf-8编码,符合servlet的规范
                    } catch (UnsupportedEncodingException e) {
                        objs[i] = value.toString(); // 不可能发生这个异常
                    }
                } else {
                    objs[i] = "";
                }

                // and remove it from querydata
                broker.removeQueryData(param);
            }

            return MessageFormat.format(pair.uri, objs);
        } else {
            return source;
        }
    }

    /**
     * @param uri
     */
    private void parserParameters(String source) {
        StringBuffer buffer = new StringBuffer("");
        int paramCount = 0;
        Map paramMap = new HashMap();
        List paramList = new ArrayList();

        for (int i = 0; i < source.length(); i++) {
            char c = source.charAt(i);

            if (c == '(') {
                // begin to get parameters
                // find next '}'char
                int index = source.indexOf(')', i);

                if (index > 0) {
                    String param = source.substring(i + 1, index);

                    if ((param != null) && (param.length() > 0)) {
                        param = param.trim();
                        i = index;
                        buffer.append('{');

                        if (!paramMap.containsKey(param)) {
                            paramList.add(param); // 使用List 保持参数的顺序.
                            paramMap.put(param, new ParameterPair(param, paramCount));
                            buffer.append(paramCount);
                            paramCount++;
                        } else {
                            buffer.append(((ParameterPair) paramMap.get(param)).position);
                        }

                        buffer.append('}');
                    }
                }
            } else {
                buffer.append(c);
            }
        }

        synchronized (cachedURI) {
            cachedURI.put(source, new URIPramPair(buffer.toString(), paramList));
        }
    }

    class URIPramPair {

        String uri;
        List   paramList;

        URIPramPair(String uri, List paramList){
            this.uri = uri;
            this.paramList = paramList;
        }
    }

    class ParameterPair {

        String param;
        int    position;

        public ParameterPair(String param, int position){
            this.param = param;
            this.position = position;
        }
    }
}
